package postgres

import (
	"context"
	"quipus/internal/database/model"
	apb "quipus/proto/gen/assist"

	_ "github.com/jackc/pgx/v5/stdlib"
	_ "github.com/joho/godotenv/autoload"
	"github.com/pkg/errors"
)

func (p *PGDB) GetLLMModel(ctx context.Context, modelId int32) (*model.LlmModel, error) {
	p.query()
	qdo := q.WithContext(ctx)
	model := qdo.LlmModel
	return model.Where(q.LlmModel.ID.Eq(modelId)).First()
}

func (p *PGDB) CreateLLMModel(ctx context.Context, create *model.LlmModel) error {
	p.query()
	qdo := q.WithContext(ctx)
	err := qdo.LlmModel.Create(create)
	if err != nil {
		return errors.Wrap(err, "failed to create llm model")
	}
	return nil
}

func (p *PGDB) DeleteLLMModel(ctx context.Context, modelId int32) error {
	p.query()
	m := q.WithContext(ctx).LlmModel
	_, err := m.Where(q.LlmModel.ID.Eq(modelId)).Delete()
	if err != nil {
		return errors.Wrap(err, "failed to delete model")
	}
	return nil
}

func (p *PGDB) UpdateLLMModel(ctx context.Context, update *apb.UpdateLLMModel) (*model.LlmModel, error) {
	p.query()
	qdo := q.WithContext(ctx)
	if update.Id < 0 {
		return nil, errors.New("id is required")
	}

	m := qdo.LlmModel
	m = m.Where(q.LlmModel.ID.Eq(update.Id))

	updateValue := &model.LlmModel{}
	updateValue.ID = update.Id
	if update.UpdatedTs > 0 {
		updateValue.UpdatedTs = update.UpdatedTs
	}

	if update.Name != "" {
		updateValue.Name = update.Name
	}

	if update.Model != "" {
		updateValue.Model = update.Model
	}

	if update.Config != "" {
		updateValue.ConfigInfo = update.Config
	}

	if update.Options != "" {
		updateValue.OptionInfo = update.Options
	}

	if len(update.Description) > 0 {
		updateValue.Description = update.Description
	}

	_, e := m.Updates(updateValue)

	return updateValue, e
}

func (p *PGDB) ListLLMModels(ctx context.Context, find *apb.FindLLMModel) ([]*model.LlmModel, int32, error) {
	p.query()
	qdo := q.WithContext(ctx)
	m := qdo.LlmModel
	if find.Id > 0 {
		m = m.Where(q.LlmModel.ID.Eq(find.Id))
	}
	if len(find.Model) > 0 {
		m = m.Where(q.LlmModel.Model.Eq(find.Model))
	}

	if len(find.Name) > 0 {
		m = m.Where(q.LlmModel.Name.Eq(find.Name))
	}

	if len(find.ModelType) > 0 {
		m = m.Where(q.LlmModel.ModelType.Eq(find.ModelType))
	}

	if find.TenantId > 0 {
		m = m.Where(q.LlmModel.TenantID.Eq(find.TenantId))
	}

	if find.ProviderId > 0 {
		m = m.Where(q.LlmModel.ProviderID.Eq(find.ProviderId))
	}

	limit := find.Limit
	if limit == 0 {
		limit = 10
	}

	ps, c, e := m.FindByPage(int(find.Offset), int(limit))

	return ps, int32(c), e
}
